﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BusTrackerSystem.Model;
using System.ComponentModel;
using System.Collections.ObjectModel;
using BusTrackerSystem.Repository;

namespace BusTrackerSystem.ViewModel
{
    public class TrackerPanelViewModel : INotifyPropertyChanged
    {
        private IBusTimesRepository _busTimesRepository;
        private string _busStopName;
        private string _busStopCode;
        private List<BusTime> _busTimes;
        private DateTime _lastRefreshed;
        private string _errorMessage;

        //TODO: Pass through a repository object here
        public TrackerPanelViewModel(string busStopName, string busStopCode, IBusTimesRepository busTimesRepository, int numberOfBusTimes)
        {
            _busTimesRepository = busTimesRepository;
            BusStopName = busStopName;
            BusStopCode = busStopCode;

            _busTimesRepository.LatestTimesUpdated += new EventHandler(_busTimesRepository_LatestTimesUpdated);
            _busTimesRepository.LatestTimeError += new EventHandler(_busTimesRepository_LatestTimeError);
            _busTimesRepository.BeginScanningLatestTimes(BusStopCode, numberOfBusTimes);
        }

        void _busTimesRepository_LatestTimeError(object sender, EventArgs e)
        {
            ErrorMessage = _busTimesRepository.ErrorMessage;
        }

        void _busTimesRepository_LatestTimesUpdated(object sender, EventArgs e)
        {
            BusTimes = _busTimesRepository.BusTimes;
            LastRefreshed = DateTime.Now;
        }

        /// <summary>
        /// The name of the bus stop, for example "Heriot-Watt Main Reception"
        /// </summary>
        public string BusStopName
        {
            get { return _busStopName; }
            set
            {
                if (_busStopName == value) return;

                _busStopName = value;
                OnPropertyChanged("BusStopName");
            }
        }

        /// <summary>
        /// The code of the bus stop as used on Lothian's bus tracker site
        /// </summary>
        public string BusStopCode
        {
            get { return _busStopCode; }
            set
            {
                if (_busStopCode == value) return;

                _busStopCode = value;
                OnPropertyChanged("BusStopCode");
            }
        }

        //TODO: Does this require sorting?
        /// <summary>
        /// A list of <see cref="BusTime"/> objects to be displayed
        /// </summary>
        public List<BusTime> BusTimes 
        {
            get { return _busTimes; }
            set
            {
                if (_busTimes == value) return;

                //TODO: Do we need to use an observable collection? See code below if so.
                //if (_busTimes != null)
                //    _busTimes.CollectionChanged -= new System.Collections.Specialized.NotifyCollectionChangedEventHandler(BusTimes_CollectionChanged);

                //_busTimes = value;

                //if (_busTimes != null)
                //    _busTimes.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(BusTimes_CollectionChanged);

                _busTimes = value;

                OnPropertyChanged("BusTimes");
            }
        }

        public DateTime LastRefreshed
        {
            get { return _lastRefreshed; }
            private set
            {
                if (_lastRefreshed == value) return;

                _lastRefreshed = value;
                OnPropertyChanged("LastRefreshed");
            }
        }

        public string ErrorMessage
        {
            get { return _errorMessage; }
            private set
            {
                if (_errorMessage == value) return;

                _errorMessage = value;
                OnPropertyChanged("ErrorMessage");
            }
        }

        #region INotifyPropertyChangedHandlers

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }
}
